using System; 
using System.Collections.Generic;
#if UNITY_EDITOR 
using UnityEditor;
#endif
using UnityEngine; 

namespace XFGameFramework.ScriptableObjectSystem
{
    /// <summary>
    /// 配表
    /// </summary>
    [CreateAssetMenu(menuName = "XFKT/ScriptableObjectSystem(配表配置)")]
    public class ScriptableObjectConfigs : ScriptableObject
    {

        #region 字段

        /// <summary>
        /// 显示名称
        /// </summary>
        [Tooltip("显示名称")]
        [Header("显示名称")]
        public string displayName;

        /// <summary>
        /// 配置集合
        /// </summary>
        [HideInInspector]
        [Tooltip("配置集合")]
        public List<ScriptableObjectData> configs = new List<ScriptableObjectData>();
         
        private Dictionary<int,ScriptableObjectData> configs_dic = new Dictionary<int, ScriptableObjectData>();

        [Tooltip("当前配表中最小的id")]
        private int minId;
        [Tooltip("当前配表中最大的id")]
        private int maxId;


        private bool isCaculateMinId = false;

        private bool isCaculateMaxId = false;

        public string excel_path;

        public string type_script_guid;

        #endregion


        #region 属性

        /// <summary>
        /// 当前配置中最小的Id
        /// </summary>
        public int MinID
        {
            get 
            {
                // 因为配表是不会在运行时发生改变的 所以这里给个标记 只计算一次就可以了
                if (!isCaculateMinId) 
                {                
                    minId = configs[0].id;
                    for (int i = 1; i < configs.Count; i++) 
                    {
                        if (minId > configs[i].id)
                            minId = configs[i].id;
                    }
                    isCaculateMinId = true;
                }

                return minId;
            }
        }


        /// <summary>
        /// 当前配置中最大的Id
        /// </summary>
        public int MaxID
        {
            get 
            {
                // 因为配表是不会在运行时发生改变的 所以这里给个标记 只计算一次就可以了
                if (!isCaculateMaxId) 
                {                 
                    maxId = configs[0].id;
                    for (int i = 1; i < configs.Count; i++)
                    {
                        if (maxId < configs[i].id)
                            maxId = configs[i].id;
                    }
                    isCaculateMaxId = true;
                }


                return maxId;
            }
        }

        #endregion

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public ScriptableObjectData GetScriptableObjectData(int id) {
             
            if(configs_dic.Count == 0) 
            {
                foreach (var item in configs)
                {

                    if(item == null) continue;

                    if (configs_dic.ContainsKey(item.id))
                        throw new Exception(string.Format("id:{0}重复!",id));
                     
                    configs_dic.Add(item.id, item);
                }
            }

            if(configs_dic.ContainsKey(id))
                return configs_dic[id];
             
            return null;
        }
        
        /// <summary>
        /// 拓展包内部使用的方法
        /// </summary>
        public void ClearCache()
        { 
            configs_dic.Clear();
        }

#if UNITY_EDITOR
        /// <summary>
        /// 拓展包内部使用的方法
        /// </summary>
        /// <returns></returns>
        public Type GetDataType()
        {
            if (!string.IsNullOrEmpty(type_script_guid))
            {
                string asset_path = AssetDatabase.GUIDToAssetPath(type_script_guid);
                MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(asset_path);
                if (script != null && script.GetClass() != null)
                {
                    Type type = script.GetClass();
                    if (type.IsSubclassOf(typeof(ScriptableObjectData)))
                        return type;
                }
            }

            return typeof(ScriptableObjectData);
        }

#endif

    }

}
